﻿using Org.BouncyCastle.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace SuperX.Helper.FileUtil
{
    public class FileHelper
    {
        /// <summary>
        /// 将文件转换成byte[]数组
        /// </summary>
        /// <param name="fileUrl">文件路径文件名称</param>
        /// <returns>byte[]数组</returns>
        public static byte[] FileToByte(string fileUrl)
        {
            try
            {
                using (FileStream fs = new FileStream(fileUrl, FileMode.Open, FileAccess.Read))
                {
                    byte[] byteArray = new byte[fs.Length];
                    fs.Read(byteArray, 0, byteArray.Length);
                    return byteArray;
                }
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 将byte[]数组保存成文件
        /// </summary>
        /// <param name="byteArray">byte[]数组</param>
        /// <param name="fileName">保存至硬盘的文件路径</param>
        /// <returns></returns>
        public static bool ByteToFile(byte[] byteArray, string fileName)
        {
            bool result = false;
            try
            {
                using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    fs.Write(byteArray, 0, byteArray.Length);
                    result = true;
                }
            }
            catch
            {
                result = false;
            }
            return result;
        }

        /// <summary>
        /// 判断文件是否被占用，如无占用会返回false，占用返回true
        /// </summary>
        /// <param name="filePath">文件的全路径</param>
        /// <param name="waitingNum">等待次数一次 1000 毫秒</param>
        /// <returns></returns>
        public static bool IsFileInUse(string filePath, int waitingNum = 5)
        {
            var num = 0;
            var IsFileInUse = true;
            do
            {
                try
                {
                    using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
                    {
                        // 如果文件被占用，上面的代码将引发 IOException 异常。
                        IsFileInUse = false;
                    }
                }
                catch (IOException)
                {
                    // 如果引发 IOException 异常，则文件正在被占用。
                    IsFileInUse = true;
                }

                num++;
                Thread.Sleep(1000);
            } while (IsFileInUse && num <= waitingNum);
            return IsFileInUse;
        }

#if !NETSTANDARD2_0
        [DllImport("kernel32.dll")]
        private static extern IntPtr _lopen(string lpPathName, int iReadWrite);

        [DllImport("kernel32.dll")]
        private static extern bool CloseHandle(IntPtr hObject);

        public static bool IsFileInUseByWinAPI(string fileName)
        {
            IntPtr vHandle = _lopen(fileName, (int)FileMode.OpenOrCreate);
            if (vHandle == IntPtr.Zero)
                return true;
            CloseHandle(vHandle);
            return false;
        }
#endif
    }
}